<?php
class View extends Object {
	private $controller;
	public function __construct(Controller &$controller) {
		$this->controller = &$controller;
	}
	private function getFriendlyPost() {
		$post = array();
		$q = explode("&",http_build_query(array_merge($_POST,$this->controller->vars)));
		foreach($q as $var) {
			list($name,$val) = explode("=",$var);
			$post[urldecode($name)] = urldecode($val); 
		}
		return $post;
	}
	private function appendPostValuesToForms($source) {
		if(isset($_POST) && !empty($_POST)) {
			$source = str_replace(chr(13),"",$source); //links fix
			$html = new DOMDocument('1.0','utf-8');
			$html->formatOutput = false;
			$html->preserveWhitespace = true;
			@$html->loadHTML($source);
			$xpath = new DOMXPath($html);
			// inputs
			foreach($this->getFriendlyPost() as $fieldName=>$value) {
				if(is_scalar($value)) {
					$inputNode = $xpath->query('//input[@name = "'.$fieldName.'"]')->item(0);
					if($inputNode && $inputNode->getAttribute("type") == "text") {
							$inputNode->setAttribute("value",$value);
					}
					if($inputNode && $inputNode->getAttribute("type") == "checkbox") {
						if((bool) $value !== false)
							$inputNode->setAttribute("checked",1);
						$inputNode->setAttribute("value",1);
					}
					if($inputNode && $inputNode->getAttribute("type") == "radio" && $inputNode->getAttribute("value") == $value) $inputNode->setAttribute("selected",1);
				}
			}
					//selects
			foreach($this->getFriendlyPost() as $fieldName=>$value) {
				if(is_scalar($value)) {
					$inputNode = $xpath->query('//select[@name = "'.$fieldName.'"]')->item(0);
					if($inputNode) {
						foreach($inputNode->childNodes as $childNode) {
							if($childNode->getAttribute("value") == $value) {
								$childNode->setAttribute("selected",1);
							}
						}
					}
				}
			}			//textareas
			foreach($this->getFriendlyPost() as $fieldName=>$value) {
				if(is_scalar($value)) {
					$inputNode = $xpath->query('//textarea[@name = "'.$fieldName.'"]')->item(0);
					if($inputNode) {
						if($inputNode->childNodes->item(0)) $inputNode->removeChild($inputNode->childNodes->item(0));
						$inputNode->appendChild($html->createTextNode($value));
					}
				}
			}
			$source = $html->saveHTML();
			$this->formatXHTML(&$source);
		}
		return $source;
	}
	static function closeXHTMLTag($tagName,&$source) {
		$source = preg_replace('/<'.$tagName.' (.*[^>])">/i', '<'.$tagName.' $1"/>', $source);
	}                                         
	public function formatXHTML(&$source) {
		$source = str_replace("<br>","<br />",$source);
		$source = str_replace("<hr>","<hr />",$source);
		self::closeXHTMLTag("input",&$source);
		self::closeXHTMLTag("link",&$source);
		self::closeXHTMLTag("img",&$source);
		self::closeXHTMLTag("meta",&$source);
	}
	public function render($_viewFile=null,$_layout=null) {
		if($_viewFile == null && 
			(
				(
					$this->controller->get("actionConfig") != null && 
					$this->controller->get("actionConfig")->view == null
				) ||
				(
					$this->controller->get("actionConfig") == null
				)
			)
		) {
			$this->controller->get("actionConfig")->view = $this->controller->controllerName.".".$this->controller->controllerAction;
		}
		if($_viewFile != null) {
			$this->controller->get("actionConfig")->view = $_viewFile;
		}
		if($_layout != null) {
			$this->controller->get("actionConfig")->layout = $_layout;
		}
		if($this->controller->get("actionConfig")) {
			if(!empty($this->controller->get("actionConfig")->exportType)) {
				$exporter = "Exporters_".$this->controller->get("actionConfig")->exportType;
				$tmp = new $exporter(); //todo: try/catch
				$vars = array();
				foreach($this->controller->get("actionConfig")->exportVars as $var) {
					$vars[$var] = $this->controller->get($var);
				}
				header('Content-type: application/x-json');
				die(call_user_func_array(array($exporter,"export"),array(&$this->controller,$vars)));
			}
			if(!empty($this->controller->get("actionConfig")->layout)) {
				$_layout = dirname($this->controller->path).DS.$this->controller->get("actionConfig")->layout.".html";
			}
			if($this->controller->get("actionConfig")->view != null) {
				$_viewFile = dirname($this->controller->path).DS.$this->controller->get("actionConfig")->view.".html";
			}
		}
		
		$content = "";
		if($_viewFile != null) {
			if(file_exists($_viewFile)) {
				ob_start();
				unset($this->controller->vars['_viewFile']); //security!
				extract($this->controller->vars);
				include($_viewFile);
				$content = ob_get_clean();
			}
			else {
				throw new Exception_ViewNotFound($_viewFile);
			}
		}
		if(isset($_layout) && !empty($_layout)) {
			if(file_exists($_layout)) {
				ob_start();
				include($_layout);
				$content = ob_get_clean();
			}
			else {
				throw new Exception_ViewNotFound("L:".$_layout);
			}
		}
		if(
			$this->controller->get("actionConfig") != null && 
			isset($this->controller->get("actionConfig")->fillForms) && 
			$this->controller->get("actionConfig")->fillForms  === true
		)
			$content = $this->appendPostValuesToForms($content);
		
		return $content;
	}
}
?>